import React, { useMemo, useRef, useState } from 'react';
import ChartElement, { type seriesDataArrayItem, type OptionsType } from '../ChartElement';
import { Button, Space, Spin, Tooltip, type TablePaginationConfig } from 'antd';
import { ProForm, ProFormDependency, ProFormList, ProFormSelect } from '@ant-design/pro-components';
import CopyableSelect from '../CopyableSelect';
import {
  BarChartOutlined,
  DeleteOutlined,
  FileImageOutlined,
  LineChartOutlined,
  RightOutlined,
  SettingOutlined,
  WarningOutlined,
} from '@ant-design/icons';
import classNames from 'classnames';
import { AnimatePresence, motion } from 'framer-motion';

interface ChartModeProps {
  columns: any[];
  dataSource: any[];
  loading?: boolean;
  isTabsTable?: boolean;
  pagination?: false | TablePaginationConfig | undefined;
  asyncPagination?: boolean;
}

const ChartMode: React.FC<ChartModeProps> = ({
  columns,
  dataSource,
  loading,
  isTabsTable,
  pagination,
  asyncPagination = false,
}) => {
  const chartRef = useRef<any>(null);
  const [show, setShow] = useState(true);
  const [chartConfig, setChartConfig] = useState<any>({
    chartType: 'line',
    xAxis: undefined,
    seriesDataArray: [],
  });
  const selecetOptions = useMemo(() => {
    if (isTabsTable) {
      return columns
        .reduce((acc, item) => {
          if (item.children) {
            return acc.concat(item.children);
          }
          return acc.concat(item);
        }, [])
        .filter((item) => !item.hideInTable)
        .map((item) => ({
          label: item.title,
          value: item.dataIndex,
        }));
    }
    return columns
      .filter((item) => !item.hideInTable)
      .map((item) => ({
        label: item.title,
        value: item.dataIndex,
      }));
  }, [columns, isTabsTable]);
  const chartTypeOptions = useMemo(() => {
    return [
      {
        label: (
          <>
            <LineChartOutlined /> 折线图
          </>
        ),
        value: 'line',
      },
      {
        label: (
          <>
            <BarChartOutlined /> 柱状图
          </>
        ),
        value: 'bar',
      },
      // { label: <><PieChartOutlined /> 饼图</>, value: 'pie' },
    ];
  }, []);

  const colorList = useMemo(
    () => [
      '24, 144, 255',
      '56, 122, 223',
      '211, 175, 247',
      '255, 173, 45',
      '253, 139, 81',
      '165, 148, 249',
      '114, 191, 120',
      '155, 236, 0',
      '255, 234, 32',
      '164, 200, 255',
      '252, 207, 77',
    ],
    [],
  );

  const options = useMemo<OptionsType>(() => {
    const { seriesDataArray, xAxis, chartType } = chartConfig;

    // 使用 Set 和 Map 来提高性能
    const xAxisDataSet = new Set();
    const valueMap = new Map();

    dataSource.forEach((item) => {
      const xValue = item[xAxis] || '';
      xAxisDataSet.add(xValue);

      if (!valueMap.has(xValue)) {
        valueMap.set(xValue, []);
      }
      valueMap.get(xValue).push(item);
    });

    const xAxisData = Array.from(xAxisDataSet);

    const seriesDataArrayResult = seriesDataArray.map(({ value, label, calculation }, index) => {
      const color = colorList[index] || {};
      const data = xAxisData.map((item) => {
        const dataItems = valueMap.get(item) || [];
        let result = 0;

        switch (calculation) {
          case 'sum':
            result = dataItems.reduce((acc, dataItem) => acc + Number(dataItem[value]), 0);
            break;
          case 'average':
            result = dataItems.length
              ? dataItems.reduce((acc, dataItem) => acc + Number(dataItem[value]), 0) /
              dataItems.length
              : 0;
            break;
          case 'max':
            result = Math.max(...dataItems.map((dataItem) => dataItem[value]));
            break;
          case 'min':
            result = Math.min(...dataItems.map((dataItem) => dataItem[value]));
            break;
          default:
            break;
        }
        return Number(result.toFixed(2));
      });

      const valueMax = Math.max(...data);
      const seriesDataItem: seriesDataArrayItem = {
        name: label,
        type: chartType,
        data,
        valueMax: (dataItem) => Number((dataItem.max * 1.2).toFixed(0)),
        yAxisIndex: 0,
      };

      // 根据 chartType 设置不同的属性
      if (chartType === 'line') {
        seriesDataItem.smooth = true;
        seriesDataItem.lineShadowColor = `rgba(${color}, 0.2)`;
        seriesDataItem.chartColor = `rgba(${color}, 0.9)`;
        seriesDataItem.tooltipColor = `rgba(${color}, 0.9)`;
        seriesDataItem.labelColor = `rgba(${color}, 0.9)`;
        if (xAxisData.length > 3000) {
          seriesDataItem.sampling = 'lttb';
        }
      } else if (chartType === 'bar') {
        seriesDataItem.labelProps = {
          show: true,
          position: 'inside',
          color: '#fff',
          fontSize: 10,
          textBorderWidth: 1,
          textBorderColor: `rgba(${color}, 0.6)`,
        };
        seriesDataItem.showBackground = index === 0;
        seriesDataItem.itemStyle = {
          color: `rgba(${color}, 0.6)`,
          borderRadius: valueMax < 0 ? [0, 0, 5, 5] : [5, 5, 0, 0],
          borderWidth: 1,
          borderColor: `rgba(${color},1)`,
        };
        seriesDataItem.large = true;
        seriesDataItem.largeThreshold = 3000;
      }

      console.log('seriesDataItem', chartType, seriesDataItem);
      return seriesDataItem;
    });

    return {
      xAxisData,
      gridPosition: ['15%', '2%', dataSource.length > 100 ? '10%' : '2%', '2%'],
      legendProps: {
        type: 'scroll',
        textStyle: {
          color: '#1890ff',
          fontSize: 12,
        },
        orient: 'horizontal',
        left: 'center',
        width: '90%',
        pageIconColor: '#99a9bf',
        pageIconInactiveColor: '#eef1f6',
        pageTextStyle: {
          color: '#475669',
        },
        top: '5%',
      },
      xAxisConfig: {
        axisLabel: {
          fontSize: 12,
          color: '#475669',
          formatter: (value: string) => {
            return value.length > 10 ? `${value.slice(0, 10)}...` : value;
          },
        },
      },
      dataZoom:
        xAxisData.length > 100
          ? [
            {
              type: 'slider',
              xAxisIndex: 0,
              filterMode: 'none',
            },
            {
              type: 'inside',
              xAxisIndex: 0,
              filterMode: 'none',
            },
          ]
          : undefined,
      seriesDataArray: seriesDataArrayResult,
    };
  }, [chartConfig, dataSource]);

  const saveAsImage = () => {
    const chartInstance = chartRef.current?.chartInstance;
    if (chartInstance) {
      const dataURL = chartInstance.getDataURL({
        pixelRatio: 2,
        backgroundColor: '#fff',
      });
      const link = document.createElement('a');
      link.download = `${chartConfig?.chartType || 'Canvas'}.png`;
      link.setAttribute('href', dataURL);
      link.click();
      link.remove();
    }
  };

  return (
    <Spin spinning={loading}>
      <div className="chart-mode">
        <div
          className={classNames('chart-mode-canvas', {
            'full-width': !show,
          })}
        >
          <Button
            icon={<FileImageOutlined />}
            key="download"
            type="link"
            className="download-button"
            onClick={saveAsImage}
          >
            下载图片
          </Button>
          <ChartElement
            ref={chartRef}
            options={options}
            style={{
              height: '100%',
              maxHeight: 'calc(100vh - 200px)',
            }}
          />
        </div>
        <div
          className={classNames('relative', {
            hidden: !show,
          })}
        >
          <div className="chart-mode-settings-close" onClick={() => setShow((prev) => !prev)}>
            <RightOutlined style={{ rotate: show ? '0deg' : '180deg' }} />
          </div>
          <AnimatePresence exitBeforeEnter>
            {show && (
              <motion.div
                key="chart-mode-settings"
                initial={{ opacity: 0, x: 100 }}
                animate={{ opacity: 1, x: 0 }}
                exit={{ opacity: 0, x: 100 }}
                className={classNames('chart-mode-settings')}
                transition={{
                  ease: 'linear',
                  type: 'tween',
                }}
              >
                <label className="chart-mode-sub_title">
                  <SettingOutlined className="color-primary mr-4" />
                  设置
                </label>
                <ProForm
                  style={{ padding: '8px 16px' }}
                  layout="vertical"
                  submitter={false}
                  initialValues={chartConfig}
                >
                  <CopyableSelect
                    name="chartType"
                    label="图表类型"
                    options={chartTypeOptions}
                    showSearch
                    fieldProps={{
                      onChange: (value) => {
                        setChartConfig((prev) => ({
                          ...prev,
                          chartType: value,
                        }));
                      },
                    }}
                  />
                  <CopyableSelect
                    name="xAxis"
                    label="横轴"
                    showSearch
                    options={selecetOptions}
                    fieldProps={{
                      onChange: (value) => {
                        setChartConfig((prev) => ({
                          ...prev,
                          xAxis: value,
                        }));
                      },
                    }}
                  />
                  <ProFormDependency name={['chartType']}>
                    {({ chartType }) => {
                      return (
                        <ProFormList
                          copyIconProps={false}
                          name="seriesDataArray"
                          label={chartType === 'pie' ? '饼图数据' : '纵轴（字段）'}
                          creatorButtonProps={{
                            position: 'bottom',
                            creatorButtonText: '添加',
                            className: 'add-button',
                          }}
                          deleteIconProps={false}
                          onAfterAdd={(data) => {
                            setChartConfig((prev) => ({
                              ...prev,
                              seriesDataArray: [
                                ...chartConfig.seriesDataArray,
                                {
                                  value: data?.value,
                                  calculation: 'sum',
                                },
                              ],
                            }));
                          }}
                          itemContainerRender={(doms) => {
                            return <ProForm.Group style={{ flex: 1 }}>{doms}</ProForm.Group>;
                          }}
                          onAfterRemove={(data, index) => {
                            setChartConfig((prev) => ({
                              ...prev,
                              seriesDataArray: chartConfig.seriesDataArray.filter(
                                (_, i) => i !== index,
                              ),
                            }));
                          }}
                        >
                          {(_, index, action) => (
                            <>
                              <Space.Compact>
                                <ProFormSelect
                                  name="value"
                                  showSearch
                                  options={selecetOptions}
                                  placeholder={'请选择字段'}
                                  fieldProps={{
                                    style: { width: 107 },
                                    dropdownStyle: { minWidth: 200 },
                                    onChange: (value) => {
                                      setChartConfig((prev) => ({
                                        ...prev,
                                        seriesDataArray: prev.seriesDataArray.map((item, i) => {
                                          if (i === index) {
                                            return {
                                              ...item,
                                              value,
                                              label: selecetOptions.find(
                                                (selecetOptionItem) =>
                                                  selecetOptionItem.value === value,
                                              )?.label,
                                            };
                                          }
                                          return item;
                                        }),
                                      }));
                                    },
                                  }}
                                />
                                <ProFormSelect
                                  name="calculation"
                                  showSearch
                                  initialValue={'sum'}
                                  placeholder={'计算方法'}
                                  options={[
                                    { label: '求和', value: 'sum' },
                                    { label: '求平均', value: 'average' },
                                    { label: '求最大值', value: 'max' },
                                    { label: '求最小值', value: 'min' },
                                  ]}
                                  allowClear={false}
                                  fieldProps={{
                                    style: { width: 80 },
                                    onChange: (value) => {
                                      setChartConfig((prev) => ({
                                        ...prev,
                                        seriesDataArray: prev.seriesDataArray.map((item, i) => {
                                          if (i === index) {
                                            return {
                                              ...item,
                                              calculation: value,
                                            };
                                          }
                                          return item;
                                        }),
                                      }));
                                    },
                                  }}
                                />
                                <Tooltip title={'删除'}>
                                  <Button
                                    onClick={() => action.remove(index)}
                                    danger
                                    type="primary"
                                    size="small"
                                    icon={<DeleteOutlined />}
                                  />
                                </Tooltip>
                              </Space.Compact>
                            </>
                          )}
                        </ProFormList>
                      );
                    }}
                  </ProFormDependency>
                </ProForm>
                {asyncPagination && pagination && (
                  <>
                    <div className="chart-mode-settings-notes">
                      <div style={{ color: '#faad14' }} className="font-weight-bold">
                        <WarningOutlined style={{ marginRight: 6 }} />
                        Notes:
                      </div>
                      <div
                        dangerouslySetInnerHTML={{
                          __html: `当前列表为<b>异步分页模式</b>,图表展示仅显示<b>${pagination.pageSize}</b>条数据,请调整分页数查看更多数据.`,
                        }}
                      />
                    </div>
                  </>
                )}
              </motion.div>
            )}
          </AnimatePresence>
        </div>
      </div>
    </Spin>
  );
};

export default ChartMode;
